#include "string.h"

namespace dys
{

    string::string(const char *c_str)
        : _size(strlen(c_str))
    {
        _str = new char[_size + 1]; // 内置类型 走初始化列表或者函数体其实区别不大, 而这里 为了程序的可维护性(不依赖声明次序),先把 _size 初始化 再给其他变量赋值
        _capacity = _size;
        strcpy(_str, c_str);
    }
    string::string(const string& str)
    {
        _str = new char[str._capacity + 1];
        strcpy(_str, str._str);
        _capacity = str._capacity;
        _size = str._size;
    }
    string& string::operator=(const string& str){
        
    }


    // string::string()
    // : _size(0) , _capacity(0), _str(new char[1]{'\0'})
    // {

    // }
    string::~string()
    {
        delete[] _str;
        _capacity = _size = 0;
    }

    void string::reserve(size_t n)
    {
        if (n > _capacity)
        {
            char *tmp = new char[n];
            strcpy(tmp, _str);
            delete _str;

            _str = tmp;
            _capacity = n;
        }
    }
    void string::append(const char *str)
    {
        size_t len = strlen(str);
        if (len + _size > _capacity)
        {
            reserve(len + _size);
        }
        ::memcpy(_str + _size, str, len);
        // ::strcpy(_str + _size, str);
        _size += len;
        _str[_size] = '\0';
    }
    void string::push_back(char ch)
    {
        if (_size == _capacity)
        {
            size_t newcapacity = _capacity == 0 ? 4 : 2 * _capacity;
            reserve(newcapacity);
        }
        _str[_size++] = ch;
        _str[_size] = '\0';
    }
    void string::insert(size_t pos, char ch)
    {
        if (_size == _capacity)
        {
            size_t newcapacity = _capacity == 0 ? 4 : 2 * _capacity;
            reserve(newcapacity);
        }
        char tmp[2] = {ch, '\0'};
        insert_aux(tmp, pos, 1);
        _size += 1;
    }
    void string::insert(size_t pos, const char *str)
    {
        assert(pos <= _size);
        size_t len = strlen(str);
        if (len + _size > _capacity)
        {
            reserve(len + _size);
        }
        insert_aux(str, pos, len);
        _size += len;
    }
    void string::erase(size_t pos, size_t len)
    {
        assert(pos < _size);
        if(len >= _size - pos){
            _str[pos] = '\0';
            _size = pos;
            return;
        }
        memcpy(_str + pos, _str + pos + len, _size - pos - len + 1);
        _size -= len;
    }
    void string::insert_aux(const char* str,int pos, int len)
    {
        for (int i = _size; i >= (int)pos; --i)
        {
            _str[i + len] = _str[i];
        }
        for (int i = 0; i < len; ++i)
        {
            _str[pos + i] = str[i];
        }
    }
    size_t string::find(char ch, size_t pos)
    {
        assert(pos < _size);
        for(size_t i = pos; i < _size; ++i){
            if(ch == _str[i]) return i;
        }
        return -1;
    }
    size_t string::find(const char* str, size_t pos)
    {
        const char* ret = strstr(_str + pos, str);
        return ret - _str;
    }

}